﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Runtime;
using System.Runtime.InteropServices;

namespace PickGold.Generic
{
	[Serializable]
	[ComVisible(true)]
	[ClassInterface(ClassInterfaceType.AutoDispatch)]
	public class CList<TYPE> : IList<TYPE>
	{
		const int CAPACITY = 10;

		private int _Count;
		private TYPE[] _List;
		private int _Capacity;

		public CList() : this(CAPACITY) { }
		public CList(int capacity)
		{
			this._Capacity = capacity;
			this.Clear();
		}
		public CList(IEnumerable<TYPE> collection)
			: this()
		{
			foreach (var item in collection)
				this.Add(item);
		}

		private void Check(bool isAdd)
		{
			if (isAdd)
			{
				if (this._Count < this._List.Length)
					return;

				var os0 = new TYPE[this._Count + CAPACITY];
				this._List.CopyTo(os0, 0);
				this._List = os0;
				return;
			}

			if (this._Capacity >= this._Count)
				return;

			if (this._Count > this._List.Length - CAPACITY)
				return;

			var os = new TYPE[this._Count + CAPACITY];
			for (var i = 0; i < this._Count; i++)
				os[i] = this._List[i];
			//this._List.CopyTo(os, 0);
			this._List = os;
		}

		#region IList<TYPE> 成员

		public int IndexOf(TYPE item)
		{
			for (var i = 0; i < this._List.Length; i++)
			{
				if (item == null && this._List[i] == null)
					return i;

				if (item == null)
					continue;

				if (this._List[i] == null)
					continue;

				if (this._List[i].Equals(item) || item.Equals(this._List[i]))
					return i;
			}

			return -1;
		}

		public void Insert(int index, TYPE item)
		{
			this.Check(true);
			for (var i = this._Count; i > 0; i--)
				this._List[i] = this._List[i - 1];
			this._Count++;
		}

		public void RemoveAt(int index)
		{
			for (var i = index; i < this._List.Length - 1; i++)
				this._List[i] = this._List[i + 1];
			this.Check(false);
			this._Count--;
		}

		public TYPE this[int index]
		{
			get
			{
				return this._List[index];
			}
			set
			{
				this._List[index] = value;
			}
		}

		#endregion

		#region ICollection<TYPE> 成员

		public void Add(TYPE item)
		{
			this.Check(true);
			this._List[this._Count] = item;
			this._Count++;
		}

		public void Clear()
		{
			this._Count = 0;
			this._List = new TYPE[this._Capacity];
		}

		public bool Contains(TYPE item)
		{
			return this.IndexOf(item) >= 0;
		}

		public void CopyTo(TYPE[] array, int arrayIndex)
		{
			for (var i = 0; i < this._List.Length; i++)
			{
				array[arrayIndex] = this._List[i];
				arrayIndex++;
			}
		}

		public int Count
		{
			get
			{
				return this._Count;
			}
		}

		public bool IsReadOnly
		{
			get
			{
				return false;
			}
		}

		public bool Remove(TYPE item)
		{
			var i = this.IndexOf(item);
			if (i < 0)
				return false;

			this.RemoveAt(i);
			return true;
		}

		#endregion

		#region IEnumerable<TYPE> 成员

		public IEnumerator<TYPE> GetEnumerator()
		{
			return this._List.GetEnumerator() as IEnumerator<TYPE>;
		}

		#endregion

		#region IEnumerable 成员

		IEnumerator IEnumerable.GetEnumerator()
		{
			return this._List.GetEnumerator();
		}

		#endregion
	}
}
